/*
 * Name 		: Chang Hyun Park
 * Student ID	: 2007******
 * Major		: Computer Engineering
 * Year			: 3rd Year
 * Subject		: File Management
 * Filename		: main.c
 */

#include "header.h"

int main(int argc, char *argv[])
{
	//Declare variables
	char* filename;
	FILE* input;
	float percent, time, startusec, endusec;
	int i, lines, temp_num, returnvalue;
	int clock_process_count=0, clock_hit_count=0, clock_miss_count=0;
	int lru_process_count=0, lru_hit_count=0, lru_miss_count=0;
	int mru_process_count=0, mru_hit_count=0, mru_miss_count=0;
	int lfu_process_count=0, lfu_hit_count=0, lfu_miss_count=0;
	int* filedata;
	int* lru_buf, *mru_buf;
	int** lfu_buf;
	long startsec, endsec;
	node* head, *victim;

	//Initialize
	filename = (char*)malloc(sizeof(char)*20);	//Limiting filename to 19 char
	input = get_filename_input(argc,argv,filename);

	buffer_size = get_buffer_size();	//buffer_size is a global variable
	head=init_linkedlist(head);	//Init linked List size=buffer_size
	init_arrays(&lru_buf, &mru_buf, &lfu_buf);

	//Read data
	lines = read_data(input,&filedata, filename); //Read input into *filedata;

	//Clock Algorithm
	victim = head;//Initialize victim address to be the same a head
	clockTime(&startsec, &startusec);
	for(i=0;i<lines;i++)
	{
		temp_num = filedata[i];
		returnvalue=clock(temp_num, head, &victim, filedata);
		if(returnvalue == -1)//error
			printf("Error with clock()!\n");
		else if(returnvalue ==0 )//miss
		{
			clock_process_count++;
			clock_miss_count++;
		}
		else if(returnvalue == 1)//hit
		{
			clock_process_count++;
			clock_hit_count++;
		}
	}
	percent = ((float)clock_hit_count/(float)clock_process_count)*100;
	clockTime(&endsec, &endusec);
	time = (endsec-startsec);
	time+= (endusec-startusec)/1000000;

	print_header();
	print_stat(percent, "Clock", clock_process_count,
			clock_hit_count, clock_miss_count, time);

	//LRU Algorithm
	clockTime(&startsec, &startusec);
	for(i=0;i<lines;i++)
	{
		temp_num = filedata[i];
		returnvalue=lru(temp_num, lru_buf, filedata, lru_process_count);
		if(returnvalue == -1)
			printf("Error with lru()!\n");
		else if(returnvalue == 1)
		{
			lru_process_count++;
			lru_hit_count++;
		}
		else if(returnvalue ==0)
		{
			lru_process_count++;
			lru_miss_count++;
		}
	}
	clockTime(&endsec, &endusec);
	time = endsec-startsec + (endusec-startusec)/1000000;
	percent = ((float)lru_hit_count/(float)lru_process_count)*100;
	print_stat(percent, "LRU", lru_process_count,
			lru_hit_count, lru_miss_count, time);

	//MRU algorithm
	clockTime(&startsec, &startusec);
	for(i=0;i<lines;i++)
	{
		temp_num = filedata[i];
		returnvalue =mru(temp_num, mru_buf, filedata, mru_process_count);
		if(returnvalue == -1)
			printf("Error with mru()!\n");
		else if(returnvalue == 1)
		{
			mru_process_count++;
			mru_hit_count++;
		}
		else if(returnvalue ==0)
		{
			mru_process_count++;
			mru_miss_count++;
		}
	}
	clockTime(&endsec, &endusec);
	time = endsec-startsec + (endusec-startusec)/1000000;
	percent = ((float)mru_hit_count/(float)mru_process_count)*100;
	print_stat(percent, "MRU", mru_process_count,
			mru_hit_count, mru_miss_count, time);

	//LFU algorithm
	clockTime(&startsec, &startusec);
	for(i=0;i<lines;i++)
	{
		temp_num = filedata[i];
		returnvalue=lfu(temp_num, lfu_buf, filedata, lfu_process_count);
		if(returnvalue == -1)
			printf("Error with lfu()!\n");
		else if(returnvalue == 1)
		{
			lfu_process_count++;
			lfu_hit_count++;
		}
		else if(returnvalue == 0)
		{
			lfu_process_count++;
			lfu_miss_count++;
		}
	}
	clockTime(&endsec, &endusec);
	time = endsec-startsec + (endusec-startusec)/1000000;
	percent = ((float)lfu_hit_count/(float)lfu_process_count)*100;
	print_stat(percent, "LFU", lfu_process_count,
			lfu_hit_count, lfu_miss_count,time);

	//Finished
	printf("Finished!");

	freemem(filename,filedata,head, lru_buf, mru_buf, lfu_buf);
	return 0;
}
